package cn.tedu.justone.pack01;

import java.util.ArrayList;
import java.util.List;

/**
 * @作者：JustOne
 * @时间：2021/8/25 - 23:18
 */
public class Demo90_案例演示wait和notify {

    public static void main(String[] args) {

        //示例：用实现生产者和消费者问题来演示wait()和notify
        //有一个盒子，
        //1、很多男生住盒子里添加花生米，如果满了则暂停。
        //2、很多女生吃着盒子里的花生米，如果空了则暂停。
        //3, 测试的看点：如果没有notify，则每个线程只能出现一次
        //4, 如果有notity，则有的线程可以出现多次。

        Box box = new Box();

        Boy b1 = new Boy(box,90);
        Boy b2 = new Boy(box,10);
        Boy b3 = new Boy(box,20);
        Boy b4 = new Boy(box,20);
        Boy b5 = new Boy(box,30);

        Girl g1 = new Girl(box,30);
        Girl g2 = new Girl(box,30);
        Girl g3 = new Girl(box,30);
        Girl g4 = new Girl(box,30);
        Girl g5 = new Girl(box,30);

        b1.start();
        b2.start();
        b3.start();
        b4.start();
        b5.start();

        g1.start();
        g2.start();
        g3.start();
        g4.start();
        g5.start();

    }
}

//Box是市场
class Box{
     private int max = 100;//盒子的最大容量
     private List<String> list = new ArrayList();//盒子

    //boy生产花生米
    public void create(int order){
        synchronized (list){
            Thread t = Thread.currentThread();
            String tName = "boy "+t.getName();
            System.out.println(tName + "进入了线程");
            //情况一：不能生产
            while(list.size() + order > max){
                System.out.println(tName + "库存量："+list.size()+"，订单量："+order+"，暂停生产");
                try {
                    System.out.println(tName+"进入了wait()");
                    list.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //情况二：可以生产
            for (int i = 0; i < order; i++) {
                list.add("米");
            }

            System.out.println(tName+"已生产："+order+"，当前库存为："+list.size());
            //list.notify();
        }
    }

    //girl吃掉花生米
    public void eat(int need){
        synchronized (list){
            Thread t = Thread.currentThread();
            String tName = "girl "+t.getName();
            System.out.println(tName + "进入了线程");
            //情况一：不够吃
            while (need > list.size()){
                System.out.println(tName + "库存量："+list.size() + "，需求量："+ need +"，暂停消费");
                try {
                    System.out.println(tName+"进入了wait()");
                    list.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //情况二：可以吃
            for (int i = 0; i < need; i++) {
                list.remove("米");
            }
            System.out.println(tName+"已吃掉："+need + "，还剩下："+list.size());
            //list.notifyAll();
        }
    }

}

//生产者
class Boy extends Thread{
    Box box;
    int num;
    public Boy(Box box, int num){
        this.box = box;
        this.num = num;
    }

    @Override
    public void run() {
        box.create(num);
    }
}

//消费者
class Girl extends Thread{
    Box box;
    int num;
    public Girl(Box box, int num){
        this.box = box;
        this.num = num;
    }

    @Override
    public void run() {
        box.eat(num);
    }
}








